// AST_Query.cpp : AST_Query class dininations
// Author: Sudhir
// 
// AST_Query -AST interface class header for querying the AST.
// 

#include "AST_Query.h"

AST_Query::AST_Query( AST *ast) {
	this->_ast = ast;
	if( this->_ast == NULL ) {
		cout << "AST un-initialized!!!!" << endl;
	}
	else if( _ast->numProcs() != 0) {
		_state.currProcPosition =0;
		_state.currProc = _ast->getProcAt (_state.currProcPosition);
		_state.currStmtNode = _state.currProc->stmtList_Head ();
		_state.firstStmtNode = _state.currProc->stmtList_Head ();
		_state.lastStmtNode = _state.currProc->stmtList_Tail ();
	}
	else { 
		_state.currStmtNode = NULL;
	}
	_State_stack.push(_state);
};

INDEX AST_Query::getFirstStmtID () {
	if( _state.currProc == NULL ||
		_state.currProc->stmtList_Head() == NULL )
		return -1;
	else
		return _state.currProc->stmtList_Head()->getStmtIndex();
};

INDEX AST_Query::getLastStmtID () {
	if( _state.currProc == NULL ||
		_state.currProc->stmtList_Head() == NULL )
		return -1;
	else
		return _state.currProc->stmtList_Tail()->getStmtIndex();
};

INTEGER AST_Query::numStmts () {
	return this->_ast->numStmts();
};

INTEGER AST_Query::numProcs () {
	if( _ast!= NULL )
		return _ast->numProcs();
	else return
		-1;
};

PROC_INDEX AST_Query::getCurrProcID () { // return -1 if no current proc exists.
	if( _state.currProc != NULL ) {
		return _state.currStmtNode->_proc_id;
	} else 
		return -1;
};

STATEMENT_TYPE AST_Query::getCurrStmtType() {
	if( _state.currStmtNode == NULL )
		return STATEMENT_Invalid;
	else return _state.currStmtNode->getStmtType();
};

INDEX AST_Query::getCurrStmtIndex() {
	if( _state.currStmtNode == NULL )
		return -1;
	else return _state.currStmtNode->getStmtIndex();
};


INDEX* AST_Query::getLinksId() {
	//INDEX linkIndecies[stmtNode::numLinks] = {stmtNode::INVALID_INDEX};
	INDEX *linkIndecies = new INDEX[stmtNode::numLinks];
	if( _state.currStmtNode == NULL )
		return NULL;
	else {
		for( int i=0; i<stmtNode::numLinks; i++) {
			if ( _state.currStmtNode->links[i] != NULL )
				linkIndecies[i] = _state.currStmtNode->links[i]->getStmtIndex();
			else 
				linkIndecies[i] = stmtNode::INVALID_INDEX;
		}
		return linkIndecies;
	};
};

// traversal APIs

STATUS AST_Query::gotoProcAt ( PROC_INDEX id ) {
	if( id < this->numProcs()) {
		_state.currProc = _ast->getProcAt ( id );
		_state.currStmtNode = _state.firstStmtNode = _state.currProc->stmtList_Head();
		_state.lastStmtNode = _state.currProc->stmtList_Tail();
		_state.currProcPosition = id;
		return STATUS_Success;
	} else 
		return STATUS_Failure;
};


STATUS AST_Query::gotoStmtAt ( STATEMENT_INDEX id ) {
	if (id > _ast->numStmts() || id < 1) {
		return STATUS_Failure;
	} else {
		_state.currStmtNode = _ast->StmtAt( id-1 );
		return STATUS_Success;
	}
};

STATUS AST_Query::gotoNextLine () {
	if( _state.currStmtNode->getStmtIndex() < _ast->numStmts() ) {
		_state.currStmtNode = _ast->StmtAt( _state.currStmtNode->getStmtIndex() );
		return STATUS_Success;
	}
	else
		return STATUS_Failure;


};

STATUS AST_Query::gotoPrevLine () {
	if( _state.currStmtNode->getStmtIndex() > 1 ) {
		_state.currStmtNode = _ast->StmtAt (_state.currStmtNode->getStmtIndex() -2 );
		return STATUS_Success;
	} else
		return STATUS_Failure;
};